#include <cs50.h>
#include <math.h>
#include <stdio.h>

#define VISA_DIGIT_1 13
#define VISA_DIGIT_2 16
#define VISA_FIRST 4
#define AMERICAN_EXPRESS_FIRST_1 34
#define AMERICAN_EXPRESS_FIRST_2 37
#define AMERICAN_EXPRESS_DIGIT 15
#define MASTER_DIGIT 16
#define MASTER_FIRST_1 51
#define MASTER_FIRST_2 52
#define MASTER_FIRST_3 53
#define MASTER_FIRST_4 54
#define MASTER_FIRST_5 55

int count_digit(long num);
string credit_card(long num, int count);
int Luhn(long num);

int main()
{
    long num = get_long("Credit cad number:");

    int count = count_digit(num);
    string company = credit_card(num, count);

    printf("%s\n", company);
}

// 位数计算
int count_digit(long num)
{
    if (num == 0)
    {
        return 1;
    }

    int count = 0;

    while (num > 0)
    {
        num /= 10;
        count++;
    }

    return count;
}

// 确认企业
string credit_card(long num, int count)
{
    double divisor = 0;

    // 获取数字前两位
    divisor = pow(10, count - 2);
    int first_two = num / divisor;

    // 获取数字前1位
    divisor = pow(10, count - 1);
    int first_one = num / divisor;

    // 美国运通卡15位，开头数字：34、37
    if ((first_two == AMERICAN_EXPRESS_FIRST_1 || first_two == AMERICAN_EXPRESS_FIRST_2) &&
        count == AMERICAN_EXPRESS_DIGIT)
    {
        // 算法验证
        int confirm = Luhn(num);
        if (confirm == 0)
        {
            return "AMEX";
        }
        else
        {
            return "INVALID";
        }
    }

    // 万事达卡16位，开头数字：51、52、53、54、55
    if ((first_two == MASTER_FIRST_1 || first_two == MASTER_FIRST_2 ||
         first_two == MASTER_FIRST_3 || first_two == MASTER_FIRST_4 ||
         first_two == MASTER_FIRST_5) &&
        count == MASTER_DIGIT)
    {
        // 算法验证
        int confirm = Luhn(num);
        if (confirm == 0)
        {
            return "MASTERCARD";
        }
        else
        {
            return "INVALID";
        }
    }
    // 维萨卡13和16位，开头数字：4
    if (first_one == VISA_FIRST && (count == VISA_DIGIT_1 || count == VISA_DIGIT_2))
    {
        // 算法验证
        int confirm = Luhn(num);
        if (confirm == 0)
        {
            return "VISA";
        }
        else
        {
            return "INVALID";
        }
    }

    return "INVALID";
}

int Luhn(long num)
{
    int sum = 0;
    int position = 1;

    // 每隔一位乘2再相加，再把没有乘2的值相加
    while (num > 0)
    {
        int digit = num % 10; // 获取num最后一位数字

        // 判断当前位数是否为偶数
        if (position % 2 == 0)
        {
            int doubled = digit * 2;

            sum += (doubled >= 10) ? (doubled - 9) : doubled;
        }
        else
        {
            sum += digit;
        }

        num /= 10;
        position++;
    }

    // 判断是否合法
    if (sum % 10 == 0)
    {
        return 0;
    }
    else
    {
        return 1;
    }
}
